package net.shop.controller;

import javax.servlet.http.HttpServletRequest;

import net.shop.common.SystemConstants;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.stereotype.Controller;

import ths.web.action.Action;
import ths.web.action.ActionContext;
import ths.web.action.ActionException;
import ths.web.action.ActionSupport;
import ths.web.action.exception.ActionExecuteException;
import ths.web.action.exception.ActionNotFoundException;
import ths.web.controller.FrontActionController;
import ths.web.i18n.Currency;
import ths.web.i18n.I18nManager;
import ths.web.i18n.Language;
import ths.web.i18n.LocaleInfo;
import ths.web.spring.BeansManager;
import ths.web.util.CookieUtils;

@Controller("frontActionController")
public class ShopFrontController extends FrontActionController {
	
	private static final String ACTION_SUFFIX = "Action";
	private static final char UNDERSCORE = '-';
	private static final char URL_SPLIT = '/';
	private static final char POINT = '.';
	
	public void prepareActionContext() throws ActionException {
		ActionContext context = ActionContext.getContext();
		HttpServletRequest request = context.getRequest();
		context.setDomain(SystemConstants.WEB_DOMAIN);
		
		Action action = getAction(request);
		context.setActionInstance(action);
		context.setActionNamespace(action.getNamespace());
		
		if (ShopFrontController.isI18nSupport()) {
			I18nManager i18n = BeansManager.getI18nManager();
			LocaleInfo locale = new LocaleInfo();
			Language language = null;
			Currency currency = null;
			
			if (i18n.isMultiLanguageSupport()) {
				String languageName = getCurrentlyLanguage(request);
				language = i18n.getLanguage(languageName);
			}
			
			if (language == null) {
				throw new ActionExecuteException("Language is null.");
			}
			
			locale.setLanguage(language);
			
			if (i18n.isMultiLanguageSupport()) {
				String currencyName = getCurrentlyCurrency(request);
				if (StringUtils.isEmpty(currencyName)) {
					currency = language.getDefalutCurrency();
				} else {
					currency = i18n.getCurrency(currencyName);
				}
				
				if (currency != null) {
					locale.setCurrency(currency);
					System.out.println(currency.getFullName());
				}
			}
			
			context.setLocaleInfo(locale);
		}
		
	}
	
	public String getViewResourceFullPath(String viewName) {
		ActionContext context = ActionContext.getContext();
		StringBuffer path = new StringBuffer();
		
		String namespace = context.getActionNamespace();
		if (FrontActionController.isI18nSupport()) {
			Language language = context.getLocaleInfo().getLanguage();
			path.append(language.getShortName()).append('/');
		}
		
		path.append(getTheme()).append('/');
		path.append(namespace).append('/');
		path.append(viewName).append(".html");
		
		return path.toString();		
	}
	
	private String getTheme() {
		return "default";
	}
	
	private ActionSupport getAction(HttpServletRequest request) throws ActionException {
		String beanName = getActionBeanName(request);
		if (StringUtils.isEmpty(beanName)) {
			throw new ActionNotFoundException(" Not found action name.");
		}
		
		Object obj;
		try {	
			obj = BeansManager.getBean(beanName);
		} catch (NoSuchBeanDefinitionException e) {
			throw new ActionNotFoundException("Not found bean["+ beanName +"] in spring.");
		}
		
		if (obj == null || !(obj instanceof ActionSupport)) {
			throw new ActionNotFoundException("is not a http action object.");
		}
		
		return (ActionSupport) obj;
	}
	
	private String getActionBeanName(HttpServletRequest request) {
		boolean hasUpper = false;
		String requestUrl = StringUtils.trimToEmpty(request.getRequestURI());
	    int length = ACTION_SUFFIX.length() + requestUrl.length() + 1;
	    if (length == 1) return requestUrl;
	    
	    int index = 0;
	    if (requestUrl.charAt(index) == URL_SPLIT ) index = 1;
	    	
	    StringBuilder buffer = new StringBuilder(length);
	    for (; index < length; index++) {
			char ch = requestUrl.charAt(index);
			if (ch == POINT) {
				break;
			} else if (Character.isWhitespace(ch)) {
				continue;
			} else if (ch == UNDERSCORE) {
				hasUpper = true;
			} else if (ch == URL_SPLIT) {
				hasUpper = true;
			} else {
				if (hasUpper) {
					buffer.append(Character.toUpperCase(ch));
					hasUpper = false;
				} else {
					buffer.append(Character.toLowerCase(ch));
				}
			}
	    }
	    
	    buffer.append(ACTION_SUFFIX);
	    return buffer.toString();			
	}
	
	private String getCurrentlyLanguage(HttpServletRequest request) {
		String serverName = request.getServerName();
		serverName = StringUtils.trimToEmpty(serverName);
		String language = "en";
		
		if (!StringUtils.isEmpty(serverName)) {
			char ch = serverName.charAt(0);
			if (!Character.isDigit(ch)) {
				StringBuilder buffer = new StringBuilder();
				for (int i = 0; i < serverName.length(); i++) {
					ch = serverName.charAt(i);
					if (ch == POINT) break;
					buffer.append(Character.toLowerCase(ch));
				}
				language = buffer.toString();
			}
		}
		
		return language;
	}
	
	private String getCurrentlyCurrency(HttpServletRequest request) {
		return CookieUtils.getCookieValue(request, SystemConstants.COOKIE_CURRENCY);
	}
}
